iT邦幫忙

2025 iThome 鐵人賽

DAY 22
0
DevOps

GitLab CI 2025:深入玩轉流水線與實戰紀錄系列 第 22

Day22 - 讓 Pipeline 的所有 Job 都在同一個 Runner 執行 - 1

  • 分享至 

  • xImage
  •  

今天的案例,來自朋友的需求。在擁有多個 GitLab Runner 執行環境中,有一個維運自動化 Pipeline 流程,希望 Pipeline 在啟動之後 Pipeline 裡的所有 Job 都可以在相同的 Runner 上執行,即當 Pipeline 上第一個 Job 被 Runner 領走後,後續的所有 Job ,都希望可以以該 Runner 執行,在 GitLab CI/CD 中,該如何辦到?

所有 Job 在同一個 Runner 下執行,會遇到什麼困難?

在 GitLab CI/CD 的架構中,GitLab Server 在建立 Pipeline 之後,會依據 CI/CD YAML 的內容,開始將待執行的 Job 放到佇列中,等待 GitLab Runner 來領工作去執行。而 Runner 可以領走 Job 的條件是,必須符合 CI/CD YAML 上宣告的 Tags 資格。所謂 Tags 資格,比喻成求職資格,就像,承接特定工作職缺,必須擁有什麼認證、通過什麼考試,如通過認證、考試符合資格的求職者很多,則這些求職者都可以徵求這個工作職缺,因此無法確認,最終會是誰取得工作。

而這個題目遇到的問題就像,系統中有多個 GitLab Runner,擁有 Job 所需執行資格的 Runner,有好幾個,假設這個 Pipeline 有 A、B、C 三個 Job,他們都只需要基本的資格,系統上大部分的 Runner 都可以滿足,因此 A、B、C 三個工作建立後,就可能會被不同的 Runner 領去執行,而無法滿足限制 Job 都被同一個 Runner 領走的需求。

那麼,這個需求可能可以怎麼滿足呢?

因為需求的目標是讓 Pipeline 上的所有 Job 都可以在同一個 Runner 上執行,而從限制在同一個 Runner 執行的角度來思考,可以借用 GitLab Runner 把 Job 接去執行的條件是「必須滿足 Job 宣告的條件(Tags)」來往下延伸,那麼是不是讓 Pipeline 建立後,透過第一個 Job 的 Script 取得該 Runner 可以決定性的 Tags 條件後,接著再透過後續的 Job 加入這個決定性條件就可以了?

什麼是 Runner 可以決定性的條件呢 ? 在 Predefined CI/CD variables 手冊中,可以注意到與 GitLab CI Runner 相關的 variable 有:

Variable Availability Description
CI_RUNNER_DESCRIPTION Job-only Runner 的描述。The description of the runner.
CI_RUNNER_EXECUTABLE_ARCH Job-only Runner 所在作業系統的執行架構。The OS/architecture of the GitLab Runner executable. Might not be the same as the environment of the executor.
CI_RUNNER_ID Job-only Runner 的唯一 ID。The unique ID of the runner being used.
CI_RUNNER_REVISION Job-only The revision of the runner running the job.
CI_RUNNER_SHORT_TOKEN Job-only The runner’s unique ID, used to authenticate new job requests. The token contains a prefix, and the first 17 characters are used.
CI_RUNNER_TAGS Job-only Runner 的 Tags。A JSON array of runner tags. For example ["tag_1", "tag_2"].
CI_RUNNER_VERSION Job-only Runner 的版本。The version of the GitLab Runner running the job.

從與 GitLab CI Runner 相關的 Pre-Defined Variables 中可以發現,看起來可以確認是哪個 Runner 的變數有:

  • CI_RUNNER_ID: Runner 的唯一 ID
  • CI_RUNNER_SHORT_TOKEN:Runner 的 Short Token
    但,這些變數並無法在目前版本的 GitLab CI/CD YAML 中用來宣告指定要由什麼 Runner 執行工作。那還可以怎麼滿足呢?

CI_RUNNER_TAGS 可能是可以用來滿足指定條件的變數,因為執行 Job 的時候,可以設定該 Job 要使用的 Tags,只要這些 Tags 足以定義到預期的 Runner,就可以拿來做宣告使用什麼 Runner 。

所以接下來只需要在建立 GitLab Runner 的時候,為專案中可以使用的 Runner 們,都建立一個可以用來識別該 Runner 的 Tag。例如流水號: Runner01、Runner02...,只要可以確保 Tag 沒有重複的 Runner 使用。

實驗一:定義好 Runner 的 Tags 之後,還缺少什麼呢?

定義好 Runner 的 Tags,讓 Tag 足以定義唯一的 Runner 後,看似已經可以實作了,也確定 Job 中的 Tags 可以以變數作為定義,因此看起來可以如下宣告:

job:
  tags: $CI_RUNNER_TAGS
  script: echo "do something"

正式編輯 GitLab CI/CD YAML 時,會發現在 Pipeline editor的介面上直接顯示錯誤,無法直接在 tags 上直接使用 CI_RUNNER_TAGS 變數,這是為什麼呢?

回顧上方的 Runner 相關變數的表格,看到所有 Runner 變數的相關欄位後方,都標注了 Job-only 代表 CI_RUNNER_TAGS 的有效區段是 Job-only,只在 Job 建立之後才存在,因此就算 tags 支援變數,這邊還是無法直接置入 CI_RUNNER_TAGS 變數。

Job-only: These variables are only made available to each job when a runner picks up the job and runs it, and:
Can be used in job scripts.
Cannot be used with trigger jobs.
Cannot be used with workflow, include or rules.

小結

我們在定義好可以指定 Runner,又知道可以使用 CI_RUNNER_TAGS 來找到指定的 Runner後,因為 CI_RUNNER_TAGS 屬於 Job-only 的變數,只在 Job 建立之後才有效,那麼我們還可以怎麼實作讓所有的 Job 可以在同一個 Runner 上執行呢? 下一篇我們會繼續實驗。如果我們的題目要再加上這些 Job 之間還要可以傳遞 Artifact、傳遞變數,又該怎麼實作?
我是墨嗓(陳佑竹),期待這次的內容能帶給你實用的啟發與幫助。

參考連結


上一篇
Day21 - 只在特定 Git Branch 的 Git Tag 執行 GitLab CI Job
下一篇
Day23 - 讓 Pipeline 的所有 Job 都在同一個 Runner 執行 - 2
系列文
GitLab CI 2025:深入玩轉流水線與實戰紀錄23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言